/**
 *
 */
package jp.seraph.same.view.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import jp.seraph.jsade.math.Angle;
import jp.seraph.jsade.model.JointIdentifier;
import jp.seraph.jsade.model.JointIdentifierContainer;
import jp.seraph.same.common.JointNameMapper;
import jp.seraph.same.controller.AgentController;
import jp.seraph.same.controller.PoseController;
import jp.seraph.same.model.PoseModel;

/**
 *
 */
public class PoseEditor extends JPanel {
    public PoseEditor(AgentController aAgentController, PoseController aPoseController, PoseModel aPoseModel, JointIdentifierContainer aJointContainer, JointNameMapper aJointNameMapper){
        mAgentController = aAgentController;
        mPoseController = aPoseController;
        mPoseModel = aPoseModel;
        mJointContainer = aJointContainer;
        mJointNameMapper = aJointNameMapper;

        initComponents();
    }

    private static final long serialVersionUID = 1L;
    private AgentController mAgentController;
    private PoseController mPoseController;
    private PoseModel mPoseModel;
    private JointIdentifierContainer mJointContainer;
    private JointNameMapper mJointNameMapper;

    private void initComponents(){
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        List<JointIdentifier> tIds = getJointList(mJointContainer);

        for (JointIdentifier tJointIdentifier : tIds) {
            this.add(this.initJointComponent(tJointIdentifier));
        }

        // TODO PoseEditorに必要な見た目をちゃんと実装すること
    }

    private JComponent initJointComponent(JointIdentifier aIdentifier){
        final JointIdentifier tId = aIdentifier;
        Angle tCurrentAngle = mPoseModel.getAngle(tId);
        Box tPanel = new Box(BoxLayout.X_AXIS);
        JLabel tLabel = new JLabel(mJointNameMapper.toDisplayName(aIdentifier), SwingConstants.RIGHT);

        int tMin = (int)tId.getMinAngle().getDegree();
        int tMax = (int)tId.getMaxAngle().getDegree();
        int tSpacing = (int) ((tMax - tMin) / 3);
        final JSlider tSlider = new JSlider(tMin, tMax, (int)tCurrentAngle.getDegree());
        final JFormattedTextField tField = new JFormattedTextField(NumberFormat.getIntegerInstance());

        tSlider.setMajorTickSpacing(tSpacing);
        tSlider.setLabelTable(tSlider.createStandardLabels(tSpacing));
        tSlider.setPaintLabels(true);
        tSlider.setPaintTicks(true);
        tSlider.addChangeListener(new ChangeListener(){
            public void stateChanged(ChangeEvent aE) {
                tField.setValue(tSlider.getValue());
            }
        });

        tField.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent aE) {
                int tFieldValue = (Integer)tField.getValue();
                if(tSlider.getValue() != tFieldValue)
                    tSlider.setValue(tFieldValue);

                mPoseController.setAngle(tId, Angle.createAngleAsDegree(tFieldValue));
                mAgentController.apply(mPoseModel);
            }
        });

        tPanel.add(tLabel);
        tPanel.add(tSlider);
        tPanel.add(tField);

        return tPanel;
    }


    private List<JointIdentifier> getJointList(JointIdentifierContainer aIdContainer){
        List<JointIdentifier> tIds = new ArrayList<JointIdentifier>();
        JointIdentifierContainer tIdContainer = aIdContainer;
        for (JointIdentifier tJointIdentifier : tIdContainer) {
            tIds.add(tJointIdentifier);
        }

        Collections.sort(tIds, new Comparator<JointIdentifier>(){
            public int compare(JointIdentifier aLeft, JointIdentifier aRight) {
                String tLeft = aLeft.toJointName();
                String tRight = aRight.toJointName();
                char tLeftHead = Character.toLowerCase(tLeft.charAt(0));
                char tLeftIndex = tLeft.charAt(tLeft.length() - 1);
                char tRightHead = Character.toLowerCase(tRight.charAt(0));
                char tRightIndex = tRight.charAt(tRight.length() - 1);

                if(tLeftHead < tRightHead)
                    return -1;
                else if(tLeftHead > tRightHead)
                    return 1;

                if(tLeftIndex < tRightIndex)
                    return -1;
                else if(tLeftIndex > tRightIndex)
                    return 1;

                return 0;
            }
        });

        return tIds;
    }
}
